Skip to content

feat: explicit defeq attribute #8419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 65 commits into from
Jun 6, 2025
Merged

feat: explicit defeq attribute #8419

merged 65 commits into from
Jun 6, 2025

Conversation

nomeata
Copy link
Collaborator

@nomeata nomeata commented May 20, 2025

This PR introduces an explicit defeq attribute to mark theorems that can be used by dsimp. The benefit of an explicit attribute over the prior logic of looking at the proof body is that we can reliably omit theorem bodies across module boundaries. It also helps with intra-file parallelism.

If a theorem is syntactically defined by := rfl, then the attribute is assumed and need not given explicitly. This is a purely syntactic check and can be fooled, e.g. if in the current namespace, rfl is not actually “the” rfl of Eq. In that case, some other syntax has be used, such as := (rfl). This is also the way to go if a theorem can be proved by defeq, but one does not actually want dsimp to use this fact.

The defeq attribute will look at the type of the declaration, not the body, to check if it really holds definitionally. Because of different reduction settings, this can sometimes go wrong. Then one should also write := (rfl), if one does not want this to be a defeq theorem. (If one does then this is currently not possible, but it’s probably a bad idea anyways).

The set_option debug.tactic.simp.checkDefEqAttr true, dsimp will warn if could not apply a lemma due to a missing defeq attribute.

With set_option backward.dsimp.useDefEqAttr.get false one can revert to the old behavior of inferring rfl-ness based on the theorem body.

Both options will go away eventually (too bad we can’t mark them as deprecated right away, see #7969)

Meta programs that generate theorems (e.g. equational theorems) can use inferDefEqAttr to set the attribute based on the theorem body of the just created declaration.

This builds on #8501 to update Init to @[expose] a fair amount of definitions that, if not exposed, would prevent some existing := rfl theorems from being defeq theorems. In the interest of starting backwards compatible, I exposed these function. Hopefully many can be un-exposed later again.

A mathlib adaption branch exists that includes both the meta programming fixes and changes to the theorems (e.g. changing := by rfl to := rfl).

With the module system there is now no special handling for defeq theorem bodies, because we don’t look at the body anymore. The previous hack is removed. The defeq-ness of the theorem needs to be checked in the context of the theorem’s type; the error message contains a hint if the defeq check fails because of the exported context.

@nomeata nomeata added the changelog-language Language features, tactics, and metaprograms label May 20, 2025
@github-actions github-actions bot added the changes-stage0 Contains stage0 changes, merge manually using rebase label May 20, 2025
@nomeata nomeata force-pushed the joachim/dsimp-attr branch from f694af3 to 88c553f Compare May 20, 2025 14:52
@github-actions github-actions bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label May 20, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request May 20, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request May 20, 2025
@leanprover-community-bot
Copy link
Collaborator

leanprover-community-bot commented May 20, 2025

Mathlib CI status (docs):

  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-05-20 15:26:26) View Log
  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-05-20 17:22:21) View Log
  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-05-21 08:40:44) View Log
  • ✅ Mathlib branch lean-pr-testing-8419 has successfully built against this PR. (2025-05-21 09:44:21) View Log
  • ✅ Mathlib branch lean-pr-testing-8419 has successfully built against this PR. (2025-05-21 10:35:45) View Log
  • ✅ Mathlib branch lean-pr-testing-8419 has successfully built against this PR. (2025-05-21 13:17:24) View Log
  • ✅ Mathlib branch lean-pr-testing-8419 has successfully built against this PR. (2025-05-21 15:21:49) View Log
  • ✅ Mathlib branch lean-pr-testing-8419 has successfully built against this PR. (2025-05-21 20:05:51) View Log
  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-05-27 16:18:55) View Log
  • ✅ Mathlib branch lean-pr-testing-8419 has successfully built against this PR. (2025-05-27 22:39:18) View Log
  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-05-28 08:47:27) View Log
  • ✅ Mathlib branch lean-pr-testing-8419 has successfully built against this PR. (2025-05-28 15:54:19) View Log
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase b9243e19bea83bfa12620e30bc79ef85d78a5c0a --onto c12159b51982221bdd66f0c5997f85e1f9d91772. You can force Mathlib CI using the force-mathlib-ci label. (2025-06-04 13:36:39)
  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-06-05 10:08:11) View Log
  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-06-05 10:30:40) View Log
  • ❗ Mathlib CI can not be attempted yet, as the nightly-testing-2025-06-05 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-mathlib, Mathlib CI should run now. You can force Mathlib CI using the force-mathlib-ci label. (2025-06-05 11:22:51)
  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-06-05 11:44:19) View Log
  • 💥 Mathlib branch lean-pr-testing-8419 build failed against this PR. (2025-06-05 12:03:59) View Log
  • 🟡 Mathlib branch lean-pr-testing-8419 build against this PR was cancelled. (2025-06-05 14:51:26) View Log
  • ✅ Mathlib branch lean-pr-testing-8419 has successfully built against this PR. (2025-06-05 15:33:30) View Log
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase eddbe0811842cd38186876ce637274f7edbb4d50 --onto 9b9dd8546a123d746580649b239f26c26d370d20. You can force Mathlib CI using the force-mathlib-ci label. (2025-06-06 18:52:51)

@leanprover-community-bot leanprover-community-bot added the breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan label May 20, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request May 20, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request May 20, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request May 21, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request May 21, 2025
@leanprover-community-bot leanprover-community-bot added builds-mathlib CI has verified that Mathlib builds against this PR and removed breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan labels May 21, 2025
@github-actions github-actions bot added the changes-stage0 Contains stage0 changes, merge manually using rebase label Jun 5, 2025
@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit 827a75f.
The entire run failed.
Found no significant differences.

@nomeata
Copy link
Collaborator Author

nomeata commented Jun 5, 2025

!bench

@nomeata nomeata force-pushed the joachim/dsimp-attr branch from f89aad0 to 1f2edc1 Compare June 5, 2025 11:57
@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit f89aad0.
There were significant changes against commit 9b9dd85:

  Benchmark                              Metric                  Change
  =================================================================================
+ Init.Data.BitVec.Lemmas re-elab        branch-misses            -2.1%   (-39.1 σ)
+ Init.Data.List.Sublist re-elab -j4     branch-misses            -2.6%   (-23.5 σ)
+ Std.Data.DHashMap.Internal.RawLemmas   branch-misses            -3.6%   (-48.3 σ)
+ binarytrees.st                         task-clock               -9.3%   (-21.5 σ)
+ binarytrees.st                         wall-clock               -9.3%   (-21.5 σ)
- bv_decide_inequality.lean              maxrss                    2.4%   (192.9 σ)
- lake build no-op                       maxrss                    7.0%    (49.1 σ)
- riscv-ast.lean                         branches                  2.4%   (153.2 σ)
- riscv-ast.lean                         instructions              2.1%    (73.4 σ)
+ stdlib                                 blocked                 -96.3% (-1160.9 σ)
- stdlib                                 blocked (unaccounted)    37.5%    (33.8 σ)

def validateDefEqAttr (declName : Name) : AttrM Unit := do
let info ← getConstVal declName
MetaM.run' do
withTransparency .all do -- we want to look through defs in `info.type` all the way to `Eq`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand this correctly,

def P := 1 = 1

@[defeq, simp]
theorem p_true : P := rfl

would get accepted and then

/-
(kernel) application type mismatch: In the application
  @id P True.intro
the final argument
  True.intro
has type
  True
but is expected to have type
  P
-/
example : P := by dsimp

(because it thinks P = True is defeq)
May have misunderstood how this attribute is supposed to work exactly though

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get

def Q := 1 = 1
@[defeq, simp] theorem Q_true : Q := rfl
/-- error: dsimp made no progress -/
#guard_msgs in example : Q := by dsimp [Q_true]

on this branch (and also before).

I think this is expected: Q_true when used by simp is turned into eq_true Q_true : Q = True, and that isn't a rfl lemma.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that will make support for Iff a bit difficult though, won't it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a regression, or are you worried about difficulties when adding new features? (I’m not worried about refactoring any of this after it lands.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding new features; but I guess yeah, it's fine to refactor so this can probably land like this for now.

@nomeata nomeata force-pushed the joachim/dsimp-attr branch from 1f2edc1 to af15d77 Compare June 5, 2025 12:41
@nomeata
Copy link
Collaborator Author

nomeata commented Jun 5, 2025

!bench

@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit af15d77.
There were significant changes against commit 9b9dd85:

  Benchmark                              Metric                  Change
  =================================================================================
- Init.Data.BitVec.Lemmas                maxrss                   16.1%    (20.9 σ)
+ Init.Data.BitVec.Lemmas                wall-clock              -38.8%  (-119.9 σ)
+ Init.Data.BitVec.Lemmas re-elab        branches                 -2.4%   (-89.4 σ)
+ Init.Data.BitVec.Lemmas re-elab        instructions             -2.3%   (-95.2 σ)
+ Std.Data.DHashMap.Internal.RawLemmas   wall-clock              -13.4%   (-32.3 σ)
- riscv-ast.lean                         branches                  2.6%    (58.8 σ)
- riscv-ast.lean                         instructions              2.3%    (44.3 σ)
- stdlib                                 attribute application    16.0%    (56.6 σ)
+ stdlib                                 blocked                 -93.4% (-1430.0 σ)
- stdlib                                 tactic execution          8.7%    (31.3 σ)
+ stdlib                                 wall-clock               -4.1%  (-145.6 σ)

This reverts commit b6838f8.
@nomeata nomeata force-pushed the joachim/dsimp-attr branch from af15d77 to 8f798af Compare June 5, 2025 14:12
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Jun 5, 2025
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Jun 5, 2025
@leanprover-community-bot leanprover-community-bot added builds-mathlib CI has verified that Mathlib builds against this PR and removed breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan labels Jun 5, 2025
@nomeata nomeata force-pushed the joachim/dsimp-attr branch from 8f798af to f6db92f Compare June 6, 2025 17:53
@nomeata nomeata changed the base branch from nightly to master June 6, 2025 17:53
@nomeata nomeata marked this pull request as ready for review June 6, 2025 18:14
@nomeata nomeata requested review from kim-em and leodemoura as code owners June 6, 2025 18:14
@nomeata nomeata enabled auto-merge June 6, 2025 18:14
@github-actions github-actions bot removed the changes-stage0 Contains stage0 changes, merge manually using rebase label Jun 6, 2025
@nomeata nomeata added this pull request to the merge queue Jun 6, 2025
Merged via the queue into master with commit 24cb133 Jun 6, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
builds-mathlib CI has verified that Mathlib builds against this PR changelog-language Language features, tactics, and metaprograms merge-ci Enable merge queue CI checks for PR. In particular, produce artifacts for all major platforms. toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants